<template>
  <div class="design-box">
    <!-- 导航栏 -->
    <design-nav @generateReport="generateReport" @reset="reset"></design-nav>
    <!-- 内容区域 -->
    <div class="bottom">
      <!-- 左侧添加模块区域 -->
      <div class="left" ref="leftRef">
        <c-scrollbar
          trigger="hover"
          :hThumbStyle="{
            'background-color': 'rgba(0,0,0,0.4)'
          }"
        >
          <Title @unflodOrCollapse="unflodOrCollapse" showCollapse></Title>
          <model-list :leftShowStatus="leftShowStatus" :key="UuidStore.refreshUuid"></model-list>
        </c-scrollbar>
      </div>

      <!-- 预览区域 -->
      <div class="center" :key="UuidStore.refreshUuid">
        <div class="design" ref="html2Pdf">
          <div class="design-content" ref="htmlContentPdf">
            <component :is="componentName" @contentHeightChange="contentHeightChange" />
          </div>
          <!-- 分页线 -->
          <template v-if="linesNumber > 0">
            <div
              class="lines"
              v-for="(item, index) in linesNumber"
              :ref="(el) => setLinesRef(el, index)"
              :style="{ top: `${1128 + 1132 * index}px` }"
            >
              <p class="tips">如果分割线遮挡内容，请通过调整模块上下边距以显示内容！</p>
              <p class="page">{{ index + 1 }}/{{ linesNumber }}</p>
            </div>
          </template>
        </div>
      </div>
      <!-- 属性设置面板 -->
      <div class="config" :key="UuidStore.refreshUuid">
        <Title :title="title"></Title>
        <component :is="useModel.optionsName" v-if="useModel.model" :key="useModel.id" />
        <global-options v-else></global-options>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { nextTick, onBeforeUnmount, onBeforeUpdate, onMounted, ref, watch } from 'vue';
  import Title from './components/Title.vue';
  import ModelList from './components/ModelList.vue';
  import GlobalOptions from '@/components/CommonOptions/GlobalOptions.vue';
  import { debounce } from 'lodash'; // 防抖函数
  import TEMPLATE_JSON from '@/schema/model';

  import downloadPDF from '@/utils/html2pdf'; // 下载为pdf
  import { useResumeModelStore, useResumeJsonStore } from '@/store/resume';
  import { storeToRefs } from 'pinia';
  import { useRoute } from 'vue-router';
  import styles from '@/schema/style';
  import { CScrollbar } from 'c-scrollbar'; // 滚动条
  import moment from 'moment'; // 日期处理
  import { IResumeJson } from '@/interface/model';
  import { openAndCloseLoadingByTime } from '@/utils/common';
  import DesignNav from './components/DesignNav.vue';
  import { useUuidStore } from '@/store/uuid';
import useAddStyle from '@/hooks/useAddStyle';

  openAndCloseLoadingByTime(1500); // 等待动画层

  const { title } = storeToRefs(useResumeModelStore());
  const store = useResumeJsonStore();
  const UuidStore = useUuidStore();
  let { resumeJsonStore } = storeToRefs(useResumeJsonStore()); // store里的模板数据

  // 重置数据方法
  const resetStoreAndLocal = () => {
    TEMPLATE_JSON.ID = id as string;
    TEMPLATE_JSON.NAME = name as string;
    let resetObj = useAddStyle(TEMPLATE_JSON); // 初始数据
    store.changeResumeJsonData(resetObj); // 更改store的数据
  };

  // 获取本地数据,初始化store里面的简历数据
  const localData = localStorage.getItem('resumeDraft');
  const route = useRoute();
  const { id, name } = route.query; // 模板id和模板名称
  resumeJsonStore.value.ID = id as string;
  resumeJsonStore.value.NAME = name as string;
  const componentName = ref<string>(name as string); // 模板名称,即渲染哪个模板
  if (localData) {
    let localObj = JSON.parse(localData)[id as string];
    if (localObj) {
      store.changeResumeJsonData(localObj);
    } else {
      resetStoreAndLocal();
    }
  } else {
    resetStoreAndLocal();
  }

  // 过滤掉模板2不需要的模块
  if (Number(id) == 2) {
    let List: any = [];
    resumeJsonStore.value.LIST.forEach((item) => {
      if (item.model == 'RESUME_TITLE') {
        item.show = false;
      }
      List.push(item);
    });
    resumeJsonStore.value.LIST = List;
  }
  console.log('designer页面setup执行', resumeJsonStore);

  // 生命周期函数
  onMounted(async () => {
    resizeDOM();
    initClickListen();
  });
  onBeforeUnmount(() => {
    observer?.disconnect();
  });
  onBeforeUpdate(() => {
    lineRefs = [];
  });

  // 属性设置
  const useModel = useResumeModelStore();
  // 全局样式设置
  const globalStyleSetting = () => {
    // 重置store选中模块
    useModel.$reset();
  };

  // 导出pdf
  const html2Pdf = ref<any>(null); // 获取元素节点
  let lineRefs: Array<any> = []; // 分割线的ref
  const setLinesRef = (el: any, index: number) => {
    if (el) {
      if (linesNumber.value === index + 1) {
        el.style.top = linesNumber.value * 1160 + 'px'; // 最后一条分割线出现在底部
      }
      lineRefs.push(el);
    }
  };

  // 重置数据
  const reset = () => {
    resetStoreAndLocal(); // 重置store数据
    globalStyleSetting(); // 重置选中模块
    // 删除本地该条数据
    let localData = localStorage.getItem('resumeDraft'); // 本地缓存数据
    if (localData) {
      let allData = JSON.parse(localData);
      if (Object.keys(allData).length > 1) {
        if (allData[id as string]) {
          delete allData[id as string]; // 删除该条数据
          localStorage.setItem('resumeDraft', JSON.stringify(allData));
        }
      } else {
        localStorage.removeItem('resumeDraft');
      }
    }
    UuidStore.setUuid(); // 重新渲染左侧列表和右侧属性面板设置
  };

  // 生成pdf方法
  const generateReport = async () => {
    let temp = linesNumber.value;
    linesNumber.value = 0;
    useModel.$reset(); // 重置选中模块
    await nextTick();
    downloadPDF(html2Pdf.value, resumeJsonStore.value.TITLE, false, () => {
      linesNumber.value = temp;
    });
  };

  // 监听内容元素高度变化，绘制分割线
  const htmlContentPdf = ref<any>(null);
  let observer: ResizeObserver | null = null;
  let height: number = 0;
  let linesNumber = ref<number>(0);
  const resizeDOM = () => {
    observer = new ResizeObserver(async (entries: ResizeObserverEntry[]) => {
      for (let entry of entries) {
        height = (entry.target as HTMLElement).offsetHeight;
        linesNumber.value = Math.ceil(height / 1160); // 有几条分割线
        html2Pdf.value.style.height = 1160 * linesNumber.value + 'px'; // 整个简历的高度
        htmlContentPdf.value.style.height = html2Pdf.value.style.height;
      }
    });
    observer.observe(htmlContentPdf.value); // 监听元素
  };

  // 子组件内容高度发生变化---需要重新计算高度，触发resizeDOM
  const contentHeightChange = (height: number) => {
    htmlContentPdf.value.style.height = height + 'px';
  };

  // 点击其它区域，取消模块选择，即取消模块选中效果
  const initClickListen = () => {
    window.addEventListener('click', dealClick);
  };
  const dealClick = (e: MouseEvent) => {
    const bool = getTargetNode(htmlContentPdf.value, e.target);
    if (bool) {
      globalStyleSetting();
    }
  };
  const getTargetNode = (ele: any, target: any): boolean => {
    if (!ele || ele === document) return false;
    return ele === target ? true : getTargetNode(ele.parentNode, target);
  };
  onBeforeUnmount(() => {
    window.removeEventListener('click', dealClick);
  });

  // 展开或收起左侧栏
  const leftRef = ref<any>(null);
  const leftShowStatus = ref<boolean>(true);
  const unflodOrCollapse = (status: boolean) => {
    if (status) {
      setTimeout(() => {
        leftShowStatus.value = status;
      }, 100);
      leftRef.value.style.width = '300px';
    } else {
      setTimeout(() => {
        leftShowStatus.value = status;
      }, 100);
      leftRef.value.style.width = '70px';
    }
  };
</script>

<style lang="less" scoped>
  .design-box {
    height: 100vh;
    width: 100%;
    box-sizing: border-box;
    overflow: hidden;
    .bottom {
      display: flex;
      width: 100%;

      .left {
        width: 300px;
        background-color: #fff;
        height: calc(100vh - 50px);
        overflow: auto;
        transition: all 0.3s;
      }

      .center {
        display: flex;
        justify-content: center;
        align-items: flex-start;
        flex: 1;
        height: calc(100vh - 50px);
        overflow: auto;

        .design {
          background: white;
          width: 820px;
          min-height: 1160px;
          margin: 30px 0;
          display: table;
          position: relative;
          .lines {
            z-index: 10;
            width: 820px;
            height: 24px;
            background: #f3f3f3 url(@/assets/images/paging_bg.png) center top no-repeat;
            user-select: none;
            pointer-events: none;
            position: absolute;
            display: flex;
            align-items: center;
            .tips {
              font-size: 9px;
              color: #c7c7c7;
            }
            .page {
              font-size: 9px;
              color: #999999;
            }
            .page {
              position: absolute;
              left: 50%;
              top: 50%;
              transform: translate(-50%, -50%);
            }
          }
        }
      }

      .config {
        width: 350px;
        background-color: #fff;
        overflow: auto;
        display: flex;
        flex-direction: column;
        height: calc(100vh - 50px);
      }
    }
  }
</style>
